package cn.bigcontainer.alt.meta.po;

import java.util.Map;

import cn.bigcontainer.alt.meta.dto.MAppDto;
import com.fasterxml.jackson.annotation.JsonIgnore;

import cn.bigcontainer.alt.common.entity.BigMap;
import cn.bigcontainer.alt.common.util.WoJsonKit;
import cn.bigcontainer.alt.common.util.WoKit;
import cn.bigcontainer.alt.meta.dto.MObjectDto;
import cn.bigcontainer.alt.meta.dto.MViewDto;
import cn.bigcontainer.alt.meta.extension.MButtonFilter;
import lombok.extern.slf4j.Slf4j;

/**
 * 按钮，不会存在单独的表中，作为json保存在cn.bigcontainer.alt.meta.po.MView#mViewButtons中
 * @author cailei
 * @date 2019-12-04
 */
@Slf4j
public class MButton implements Comparable<MButton> {
	
	/**
	 * color:btn-default,btn-primary,btn-danger,btn-info,btn-warning
	 */
	public final static String PARAM_COLOR = "color";

	/**
	 * 表单为只读时该按钮也显示，1-true，0-false
	 */
	public final static String PARAM_REQUIRED = "required";
	
	/**
	 * 按钮类型为requestJson时的url
	 */
	public final static String PARAM_URL_REQ = "requestUrl";
	
	/**
	 * 按钮类型为openTab时的类型，包括：url/view/app
	 */
	public final static String PARAM_TAB_TYPE = "tabType";
	
	/**
	 * 按钮类型为openTab时的url
	 */
	public final static String PARAM_TAB_URL = "tabUrl";
	
	/**
	 * 按钮类型为openTab时的视图ID
	 */
	public final static String PARAM_TAB_VIEW = "tabView";
	
	/**
	 * 按钮类型为openTab时的应用ID
	 */
	public final static String PARAM_TAB_APP = "tabApp";
	
	/**
	 * 按钮类型为openTab时的应用ID
	 */
	public final static String PARAM_TAB_APP_DATA = "tabAppData";
	
	/**
	 * 按钮类型为openTab弹出视图页面后成功提交或者requestJson成功提交时的动作：refreshTab/refreshList/keepTab
	 */
	public final static String PARAM_TAB_VIEW_SUBMIT = "tabViewSubmit";
	
	/**
	 * mData中的参数：选择类型，具体值为：SEL_SINGLE等
	 */
	public final static String PARAM_SEL = "selectType";

	/**
	 * data中的参数：选择类型，具体值为：SEL_SINGLE等
	 */
	public final static String PARAM_FILTER = "buttonFilter";
	
	/**
	 * 选择类型：单选
	 */
	public final static String SEL_SINGLE = "single";
	
	/**
	 * 选择类型：多选
	 */
	public final static String SEL_MULTIPLE = "multiple";
	
	/**
	 * 选择类型：PARAM_SEL的默认值，不论选择与否
	 */
	public final static String SEL_NONE = "none";
	
	/**
	 * 选择类型：单选或不选
	 */
	public final static String SEL_SINGLE_NONE = "singleornone";

	/**
	 * 类型：新建
	 */
	public final static String TYPE_CREATE = "create";
	/**
	 * 类型：修改
	 */
	public final static String TYPE_UPDATE = "update";
	/**
	 * 类型：删除
	 */
	public final static String TYPE_DELETE = "delete";
	/**
	 * 类型：打开Tab
	 */
	public final static String TYPE_OPEN_TAB = "openTab";
	/**
	 * 类型：请求Json
	 */
	public final static String TYPE_REQUEST_JSON = "requestJson";
	/**
	 * 类型：对象选择器的确定按钮
	 */
	public final static String TYPE_SELECT = "select";
	/**
	 * 类型：对象选择器的取消按钮
	 */
	public final static String TYPE_SELECT_CANCEL = "selectCancel";

	/**
	 * 类型：新建表单提交
	 */
	public final static String TYPE_SUBMIT_CREATE = "submitCreate";
	/**
	 * 类型：修改表单提交
	 */
	public final static String TYPE_SUBMIT_UPDATE = "submitUpdate";
	/**
	 * 类型：重置
	 */
	public final static String TYPE_RESET = "reset";
	/**
	 * 类型：取消
	 */
	public final static String TYPE_CANCEL = "cancel";

	private String id;

	private String name;

	private Integer index;

	private String description;

	private String icon;

	private String type;

	private BigMap<String, Object> data = new BigMap<>();

	/**
	 * 该数据当按钮点击时，会提交到相应的request中
	 */
	private BigMap<String, Object> request = new BigMap<>();
	
	public BigMap<String, Object> getRequest() {
		return request;
	}

	public void setRequest(BigMap<String, Object> request) {
		this.request = request;
	}

	/**
	 * 内存数据，不需要序列化
	 */
	@JsonIgnore
	private MViewDto view;

	/**
	 * @return
	 */
	@JsonIgnore
	public String getUrl() {
		if (WoKit.isEmpty(this.getType())) {
			return data.getString(MObjectDto.PARAM_URL);
		}
		String root = data.getString(MObjectDto.PARAM_URL_ROOT);
		if (WoKit.isEmpty(root)) {
			return "meta/" + getView().getType() + "/buttons/" + this.getType();
		}
		return root + this.getType();
	}

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Integer getIndex() {
		return index;
	}

	public void setIndex(Integer index) {
		this.index = index;
	}

	public String getDescription() {
		return description;
	}

	public void setDescription(String description) {
		this.description = description;
	}

	public String getIcon() {
		return icon;
	}

	public void setIcon(String icon) {
		this.icon = icon;
	}

	public String getType() {
		return type;
	}

	public void setType(String type) {
		this.type = type;
	}

	public BigMap<String, Object> getData() {
		return data;
	}

	public void setData(BigMap<String, Object> data) {
		this.data = data;
	}

	public MViewDto getView() {
		return view;
	}

	public void setView(MViewDto view) {
		this.view = view;
	}

	@JsonIgnore
	public Boolean getMetaShow () {
		return data.getBoolean(MObjectDto.PARAM_META_SHOW, false);
	}

	public void setMetaShow (Boolean metaShow) {
		data.put(MObjectDto.PARAM_META_SHOW, metaShow);
	}
	
	public void setUrl (String value) {
		data.bigPut(MObjectDto.PARAM_URL, value);
	}
	
	public void setSelectType (String value){
		data.bigPut(PARAM_SEL, value);
	}
	
	public void setRequired (String value){
		data.bigPut(PARAM_REQUIRED, value);
	}
	
	public void setRequestUrl (String value){
		data.bigPut(PARAM_URL_REQ, value);
	}
	
	public void setTabType (String value){
		data.bigPut(PARAM_TAB_TYPE, value);
	}
	
	public void setTabView (String value){
		data.bigPut(PARAM_TAB_VIEW, value);
	}
	
	public void setTabApp (String value){
		data.bigPut(PARAM_TAB_APP, value);
	}
	
	public void setTabAppData (MApp value){
		data.bigPut(PARAM_TAB_APP_DATA, WoJsonKit.writeAsString(value));
	}
	
	public void setTabUrl (String value){
		data.bigPut(PARAM_TAB_URL, value);
	}
	
	public void setTabViewSubmit (String value){
		data.bigPut(PARAM_TAB_VIEW_SUBMIT, value);
	}
	
	public void setColor (String value){
		data.bigPut(PARAM_COLOR, value);
	}
	
	public void setRequestData (String data) {
		if (WoKit.isEmpty(data)) {
			request.clear();
		} else {
			request.putAll(WoJsonKit.readAsType(data, Map.class));
		}
	}
	
	@JsonIgnore
	public String getRequestData() {
		return WoJsonKit.writeAsString(request);
	}
	
	@Override
    public int compareTo(MButton o) {
		if (data.bigEquals(PARAM_SEL, SEL_SINGLE) && o.getData().bigEquals(PARAM_SEL, SEL_SINGLE)) {
			return this.getIndex() - o.getIndex();
		}
		if (!data.bigEquals(PARAM_SEL, SEL_SINGLE) && !o.getData().bigEquals(PARAM_SEL, SEL_SINGLE)) {
			return this.getIndex() - o.getIndex();
		}
		if (data.bigEquals(PARAM_SEL, SEL_SINGLE)) {
			return 1;
		}
        return -1;
    }
	
	@JsonIgnore
	public Boolean isSingleSelect () {
		return SEL_SINGLE.equals(data.getString(PARAM_SEL));
	}
	
	public String getButtonFilterBeanId () {
		return data.getString(PARAM_FILTER);
	}
	
	public Boolean isVisible (Map<String, Object> row) {
		String beanId = getButtonFilterBeanId ();
		if (WoKit.isEmpty(beanId)) {
			return true;
		}

		row.putAll(getData());
		row.putAll(getView().getApp().getObject().getRequest());

		MButtonFilter bean = null;
		if (beanId.indexOf('$') >= 0) {
			bean = WoKit.getBean(MButtonFilter.class, MButtonFilter.DEFAULT);
		} else {
			bean = WoKit.getBean(MButtonFilter.class, beanId);
		}
		return bean.isVisible(this, row);
	}
}
